﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

public class FillLetterHolder : MonoBehaviour, IEasyTimer
{
    public bool bTimerCallback
    {
        get { return this == null ? false : true; }
    }


    private const string TEXTURE_BASE_PATH = EnglishColoursPath.englishColorLetterTexturePath;



    public string letter
    {
        get;
        private set;
    }

    public string letterAudio
    {
        get;
        private set;
    }

    public bool isComplete
    {
        get;
        private set;
    }
    public Vector3 letterLinePos
    {
        get { return letterLine.rectTransform.position; }
    }

    public bool isInteractable
    {
        set { GetComponent<Graphic>().raycastTarget = value; }
    }

    public Quaternion letterStartRotation { get; set; }

    private Image letterImg;
    private Image letterLine;

    private Vector3 m_startPos;
    private Vector3 m_moveDir;

    private bool isMoving;
    private string m_triggerName;
    private float m_moveSpeed = 1;
    private float m_rotateSpeed = 1;


    private void Awake()
    {
        letterImg = GetComponent<Image>();
        letterLine = transform.childCount == 1 ? transform.GetChild(0).GetComponent<Image>() : null;
    }

    private void Update()
    {
        if (isMoving)
        {
            transform.position += m_moveDir * Time.deltaTime * m_moveSpeed;
            transform.Rotate(new Vector3(0, 0, Time.deltaTime * m_rotateSpeed));

            m_moveSpeed -= Time.deltaTime * 0.02f;
        }
    }

    public void Initialize(string letter, string letterAudio, bool isLineHolder)
    {
        this.letter = letter;
        this.letterAudio = letterAudio;
        isInteractable = false;
        isComplete = false;

        if (isLineHolder)
        {
            Sprite sprite = LoadLineSprite(this.letter);
            letterImg.sprite = sprite;
            letterLine.sprite = sprite;
            letterImg.SetNativeSize();
            letterLine.SetNativeSize();
            letterLine.rectTransform.anchoredPosition3D = GetLetterOffset(this.letter);
        }
        else
        {
            Sprite sprite = LoadSprite(this.letter);
            letterImg.sprite = sprite;
            letterImg.SetNativeSize();
        }
    }

    public void MixToPos(Vector3 pos)
    {
        m_moveDir = pos - transform.position;
        isMoving = true;

        m_moveSpeed = Random.Range(0.5f, 1.5f);

        float time = Random.Range(1f, 1.5f);
        this.AddTimerEx(time, () => {
            isMoving = false;
            m_startPos = transform.position;
        });
        transform.DORotate(new Vector3(0, 0, Random.Range(-6, 6) * 360 + Random.Range(-30, 30)), time).SetEase(Ease.Linear).OnComplete(()=> { letterStartRotation = transform.rotation; isInteractable = true; });

        //float duration = 1.5f;
        //transform.DORotate(new Vector3(0, 0, Random.Range(-6, 6) * 360 + Random.Range(-30,30)), duration).SetEase(Ease.Linear);
        //transform.DOMove(pos, duration).SetEase(Ease.Linear);

        //Vector3 dir = transform.position - pos;
        //Vector3 centerPos = pos + dir * Random.Range(0.3f, 0.7f);
        //Vector3 upPos = centerPos + new Vector3(0, dir.y, 0) * Random.Range(0.5f, 2f);
        //Vector3[] path = new Vector3[3] { transform.position, upPos, pos };

        //transform.DORotate(new Vector3(0, 0, Random.Range(-6, 6)) * 360, duration).SetEase(Ease.Linear);
        //transform.DOPath(path, duration, PathType.CatmullRom).SetEase(Ease.Linear);
    }

    public void PlayHintAnim()
    {
        //transform.DOPunchScale(Vector3.one * 1.5f, 0.5f, 3);
        transform.DOPunchRotation(new Vector3(0, 0, 30), 1f, 6);
    }

    public void UpdateCompleteState(bool val)
    {
        isComplete = val;
    }

    public void MoveBackStartPos()
    {
        transform.DOMove(m_startPos, 0.3f);
    }

    public void PlayCompleteAnim(Transform parent, Vector3 pos)
    {
        UpdateCompleteState(true);
        transform.SetParent(parent);
        transform.DOMove(pos, 0.3f);
        transform.DOLocalRotate(Vector3.zero, 0.3f);
    }

    private Sprite LoadSprite(string letter)
    {
        return Res.LoadSprite(TEXTURE_BASE_PATH + letter);
    }

    private Sprite LoadLineSprite(string letter)
    {
        return Res.LoadSprite(TEXTURE_BASE_PATH + letter + "_1");
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (m_triggerName == collision.name)
            return;
        m_triggerName = collision.name;
        //isMoving = false;

        //Debug.LogError(collision.name);
        Vector3 normal = GetNormal(collision.name);
        m_moveDir = ReflectVector3(m_moveDir, normal);
    }

    private Vector3 ReflectVector3(Vector3 inDir, Vector3 normal)
    {
        Vector3 projectPoint = Vector3.Project(-inDir, normal);
        return inDir + 2 * projectPoint.magnitude *  normal;
    }

    private Vector3 GetNormal(string name)
    {
        switch (name)
        {
            case "LeftCollider":
                return Vector3.right;
            case "RightCollider":
                return Vector3.left;
            case "TopCollider":
                return Vector3.down;
            case "BottomCollider":
                return Vector3.up;
        }
        return Vector3.zero;
    }

    private Vector3 GetLetterOffset(string letter)
    {
        switch (letter)
        {
            case "a":
            case "c":
            case "e":
            case "m":
            case "n":
            case "o":
            case "r":
            case "s":
            case "u":
            case "v":
            case "w":
            case "x":
            case "z":
                return Vector3.zero;
            case "y":
            case "j":
            case "g":
            case "p":
            case "q":
                return new Vector3(0, -41.5f, 0);
            case "b":
            case "d":
            case "f":
            case "h":
            case "k":
            case "l":
            case "i":
                return new Vector3(0, 45, 0);
            case "t":
                return new Vector3(0, 33, 0);
            default:
                return new Vector3(0, 0, 0);
        }
    }


}
